function intepretTemplate(code)
	if (code) then
		--code = code:gsub("(%s+)(<#[^=]-#>)", function (a, b) if b:sub(-1)=="=" then return a..b else return b end end )
		--code = code:gsub("([ %t]+<#=?)", function (a) if a:sub(-1)=="=" then return a else return "<#" end end )
		--code = code:gsub("(#>%s+\n)", function (a) if a:sub(-1)=="\n" then return "#>" else return a end end )
		--code = code:gsub("(#>[\t ]*\n)", function (a) return "#>"end )
		code = code:gsub("(\n[\t ]+<#)(=?)", function (a, b) if b=="=" then return a..b else return "\n<#"end end )

		local lastpos=1
		local pos=0
		local spos

		local dstcode =" "

		while true do
			lastpos=pos+1
			spos,pos,eqs,cd = code:find("<#(=?)(.-)#>",pos)
			--print("------spos,pos-------")
			--print(spos,pos)
			--print("------eqs,cd-------")
			--print(eqs,cd)

			if not spos then
				dstcode=dstcode.."theFile:write(\[\["..code:sub(lastpos).."\]\])\n"
				break
			elseif( lastpos<spos) then
				dstcode=dstcode.."theFile:write(\[\["..code:sub(lastpos,spos-1).."\]\])\n"
			end

			if eqs=="=" then
				dstcode=dstcode.."theFile:write("..cd..")\n"
			else
				dstcode=dstcode..cd.."\n"
			end
		end
		return dstcode
	end
end

--[[
--
--	loadTemplate
--	load and compile an template file into a callable object, which is used to generate code base on this
--	template tags:
--	<# ...  #> : embbeded code block
--	<#= ... #> : embbeded value
--
--]]
function loadTemplate(filename)
	local tf = assert(io.open(filename,"r"))
	local code = tf:read("*all")
	tf:close()
	code = intepretTemplate(code)
	return loadstring(code)
end

function debugTemplate(filename)
	local tf = assert(io.open(filename,"r"))
	local code = tf:read("*all")
	tf:close()
	code = intepretTemplate(code)
	local tpl = loadstring(code)
	print("------------------------------------------")
	tf= io.open("error.lua", "w");
	tf:write(code)
	tf:close()
	dofile("error.lua")
	print("------------------------------------------")
end

function showTemplate(filename)
	local tf = assert(io.open(filename,"r"))
	local code = tf:read("*all")
	tf:close()
	code = intepretTemplate(code)
	print("______________________________________________________")
	print(code)
	print("======================================================")
end

function dumpTemplate(filename, outputfile)
	local tf = assert(io.open(filename,"r"))
	local code = tf:read("*all")
	tf:close()
	code = intepretTemplate(code)
	print("------------------------------------------")
	print("Template [" .. filename .."] already been dumped into [" ..outputfile .."]")
	tf= io.open(outputfile, "w");
	tf:write(code)
end

--[[
--	bind
--	which bind data to template to generat the destination code
--
--]]
function bind(template_file, data_file, output_file)
	if template_file and data_file and output_file then
		local tpl = loadTemplate(template_file)
		if tpl then
			if data_file and data_file~="" then
			local data_f = loadfile(data_file)
				if data_f then
					data_f()
				else
					print ("binding failed, invalid data file : " , data_file)
					return
				end
			end
			theFile = io.open(output_file, "w")
			if theFile then
				print ("binding ... [" , data_file , "] + [" , template_file , "] = [" , output_file, "]")
				tpl()
				theFile:close()
			else
				print ("binding failed, invlaid output file : ", output_file)
			end
		else
			print ("binding failed, invalid template :  ", template_file)
			debugTemplate(template_file)
		end
	else
		print(" binding failed, missing parameter!!!")
	end
end
